home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #3 / Amiga Plus CD - 1997 - No. 03.iso / pd / programmierung / vbcc / main.c < prev    next >
C/C++ Source or Header  |  1997-01-17  |  28KB  |  772 lines

  1. /*  $VER: vbcc (main.c) V0.4    */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int endok=1;
  8. int line,errors;
  9.  
  10. char errfname[FILENAME_MAX+1]; /*  VORSICHT: Diese Konstante kommt nochmal vor */
  11.  
  12. char *multname[]={"","s"};
  13. void raus(void)
  14. /*  Beendet das Programm                                            */
  15. {
  16.     if(DEBUG) printf("raus()\n");
  17.     if(!endok) printf("unexpected end of file\n");
  18.     if(errors) printf("%d error%s found!\n",errors,multname[errors>1]);
  19.     while(nesting>=0) leave_block();
  20.     if(in[0]&&(c_flags[17]&USEDFLAG)) fclose(in[0]);
  21.     cleanup_cg(out);
  22.     if(ppout) fclose(ppout);
  23.     if(out) fclose(out);
  24.     if(ic1) fclose(ic1);
  25.     if(ic2) fclose(ic2);
  26.     if(!(c_flags[17]&USEDFLAG)) pp_free();
  27.     if(endok&&!errors) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE);
  28. }
  29.  
  30. int eof;
  31.  
  32. void translation_unit(void)
  33. /*  bearbeitet translation_unit                                     */
  34. /*  hier z.Z. nur provisorisch                                      */
  35. {
  36.     while(1){
  37.         killsp();
  38.         if(c_flags[18]&USEDFLAG){
  39.             if(*s==EOF) raus();
  40.             fputs(string,ppout);fputc('\n',ppout);
  41.             s=string;*s=0;
  42.         }else{
  43.             if(eof||(!isalpha((unsigned char)*s)&&*s!='_')){
  44.                 if(!eof) error(0);
  45.                 raus();
  46.             }
  47.             endok=0;
  48.             var_declaration();
  49.             endok=1;
  50.         }
  51.     }
  52. }
  53.  
  54. void dontwarn(char *p)
  55. /*  schaltet flags fuer Meldung auf DONTWARN    */
  56. {
  57.     int i;
  58.     if(*p!='=') error(4,"-dontwarn");
  59.     i=atoi(p+1);
  60.     if(i>=err_num) error(159,i);
  61.     if(i<0){
  62.         for(i=0;i<err_num;i++)
  63.             if(!(err_out[i].flags&(ANSIV|FATAL)))
  64.                 err_out[i].flags|=DONTWARN;
  65.         return;
  66.     }
  67.     if(err_out[i].flags&(ANSIV|FATAL)) error(160,i);
  68.     err_out[i].flags|=DONTWARN;
  69. }
  70. void warn(char *p)
  71. /*  schaltet Warnung fuer Meldung ein           */
  72. /*  wenn Nummer<0 sind alle Warnungen ein       */
  73. {
  74.     int i;
  75.     if(*p!='=') error(4,"-warn");
  76.     i=atoi(p+1);
  77.     if(i>=err_num) error(159,i);
  78.     if(i<0){
  79.         for(i=0;i<err_num;i++) err_out[i].flags&=~DONTWARN;
  80.         return;
  81.     }else err_out[i].flags&=~DONTWARN;
  82. }
  83.  
  84. extern char *copyright;
  85.  
  86. int main(int argc,char *argv[])
  87. {
  88.     int i,j,fname=0;
  89.     c_flags_val[9].f=dontwarn;
  90.     c_flags_val[10].f=warn;
  91.     for(i=1;i<argc;i++){
  92.         if(*argv[i]!='-'){  /*  kein Flag   */
  93.             if(fname){
  94.                 error(1);
  95.             }else fname=i;
  96.         }else{
  97.             int flag=0;
  98.             for(j=0;j<MAXCF&&flag==0;j++){
  99.                 size_t l;
  100.                 if(!c_flags_name[j]) continue;
  101.                 l=strlen(c_flags_name[j]);
  102.                 if(l>0&&!strncmp(argv[i]+1,c_flags_name[j],l)){
  103.                     flag=1;
  104.                     if((c_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  105.                     c_flags[j]|=USEDFLAG;
  106.                     if(c_flags[j]&STRINGFLAG){
  107.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  108.                         if(argv[i][l+2]||i>=argc-1)
  109.                             c_flags_val[j].p=&argv[i][l+2];
  110.                         else
  111.                             c_flags_val[j].p=&argv[++i][0];
  112.                     }
  113.                     if(c_flags[j]&VALFLAG){
  114.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  115.                         if(argv[i][l+2]||i>=argc-1)
  116.                             c_flags_val[j].l=atol(&argv[i][l+2]);
  117.                         else
  118.                             c_flags_val[j].l=atol(&argv[++i][0]);
  119.                     }
  120.                     if(c_flags[j]&FUNCFLAG) c_flags_val[j].f(&argv[i][l+1]);
  121.                 }
  122.             }
  123.             for(j=0;j<MAXGF&&flag==0;j++){
  124.                 size_t l;
  125.                 if(!g_flags_name[j]) continue;
  126.                 l=strlen(g_flags_name[j]);
  127.                 if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){
  128.                     flag=1;
  129.                     if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
  130.                     g_flags[j]|=USEDFLAG;
  131.                     if(g_flags[j]&STRINGFLAG){
  132.                         if(argv[i][l+1]!='='){error(3,argv[i]);}
  133.                         if(argv[i][l+2]||i>=argc-1)
  134.                             g_flags_val[j].p=&argv[i][l+2];
  135.                         else
  136.                             g_flags_val[j].p=&argv[++i][0];
  137.                     }
  138.                     if(g_flags[j]&VALFLAG){
  139.                         if(argv[i][l+1]!='='){error(4,argv[i]);}
  140.                         if(argv[i][l+2]||i>=argc-1)
  141.                             g_flags_val[j].l=atol(&argv[i][l+2]);
  142.                         else
  143.                             g_flags_val[j].l=atol(&argv[++i][0]);
  144.                     }
  145.                     if(g_flags[j]&FUNCFLAG) g_flags_val[j].f(&argv[i][l+1]);
  146.                 }
  147.             }
  148.             if(!flag){error(5,argv[i]);}
  149.         }
  150.     }
  151.     if(!(c_flags[6]&USEDFLAG)) printf(copyright);
  152.     if(!(c_flags[17]&USEDFLAG)) pp_init();
  153.     if(!(c_flags[8]&USEDFLAG)) c_flags_val[8].l=10; /* max. Fehlerzahl */
  154.     if(c_flags[22]&USEDFLAG) c_flags[7]|=USEDFLAG;   /*  iso=ansi */
  155.     if(c_flags[7]&USEDFLAG) error(209);
  156.     if(!fname){error(6);}
  157.     inname=argv[fname];
  158.     strncpy(errfname,inname,FILENAME_MAX);    /*  das hier ist Muell - wird noch geaendert    */
  159.     if(!init_cg()) exit(EXIT_FAILURE);
  160.     if(c_flags[17]&USEDFLAG){
  161.         in[0]=fopen(inname,"r");
  162.         if(!in[0]) {error(7,inname);}
  163.     }else{
  164.         if(!pp_include(inname)) error(7,inname);
  165.     }
  166.     if(!(c_flags[18]&USEDFLAG)&&!(c_flags[5]&USEDFLAG)){
  167.         if(c_flags[1]&USEDFLAG){
  168.             out=open_out(c_flags_val[1].p,0);
  169.         }else{
  170.             out=open_out(inname,"asm");
  171.         }
  172.         if(!out){
  173.             if(c_flags[17]&USEDFLAG){
  174.                 fclose(in[0]);
  175.             }else{
  176.                 pp_free();
  177.             }
  178.             exit(EXIT_FAILURE);
  179.         }
  180.     }
  181.     if(c_flags[2]&USEDFLAG) ic1=open_out(inname,"ic1");
  182.     if(c_flags[3]&USEDFLAG) ic2=open_out(inname,"ic2");
  183.     if(c_flags[18]&USEDFLAG) ppout=open_out(inname,"i");
  184.     if(c_flags[4]&USEDFLAG) DEBUG=c_flags_val[4].l; else DEBUG=0;
  185.     switch_count=0;break_label=0;
  186.     *string=0;s=string;line=0;
  187.     killsp();
  188.     nesting=-1;enter_block();
  189.     translation_unit();
  190. }
  191.  
  192. void prd(FILE *o,struct Typ *p)
  193. /* Gibt einen Typ auf dem Bildschirm aus    */
  194. {
  195.     int f;
  196.     if(!p) {fprintf(o,"empty type ");return;}
  197.     f=p->flags;
  198. /*    fprintf(o,"(Sizeof=%ld,flags=%d)",zl2l(szof(p)),f);*/
  199.     if(type_uncomplete(p)) {fprintf(o,"incomplete ");}
  200.     if(f&CONST) {fprintf(o,"const ");f&=~CONST;}
  201.     if(f&STRINGCONST) {fprintf(o,"string-const ");f&=~STRINGCONST;}
  202.     if(f&VOLATILE) {fprintf(o,"volatile ");f&=~VOLATILE;}
  203.     if(f&UNSIGNED) {fprintf(o,"unsigned ");f&=~UNSIGNED;}
  204.     if(f==FUNKT) {fprintf(o,"function with parameters (");
  205.                   prl(o,p->exact);
  206.                   fprintf(o,") returning ");prd(o,p->next);return;}
  207.     if(f==STRUCT){fprintf(o,"struct with components {");
  208.                   prl(o,p->exact);fprintf(o,"} ");
  209.                   return;
  210.     }
  211.     if(f==UNION) {fprintf(o,"union with components {");
  212.                   prl(o,p->exact);fprintf(o,"} ");
  213.                   return;
  214.     }
  215.     if(f==POINTER) {fprintf(o,"pointer to ");prd(o,p->next);return;}
  216.     if(f==ARRAY) {fprintf(o,"array [size %ld] of ",zl2l(p->size));prd(o,p->next);return;}
  217.     fprintf(o,"%s",typname[f]);
  218. }
  219. void prl(FILE *o,struct struct_declaration *p)
  220. /* Gibt eine struct_declaration auf dem Bildschirm aus */
  221. {
  222.     int i;
  223.     for(i=0;i<p->count;i++) {fprintf(o," %d.:",i); prd(o,(*p->sl)[i].styp);}
  224. }
  225. void freetyp(struct Typ *p)
  226. /* Gibt eine Typ-Liste frei, aber keine struct_declaration oder so */
  227. {
  228.     int f;struct Typ *merk;
  229.     if(DEBUG&8){printf("freetyp: ");prd(stdout,p);printf("\n");}
  230.     while(p){
  231.         merk=p->next;
  232.         f=p->flags&15;
  233.         if(merk&&f!=ARRAY&&f!=POINTER&&f!=FUNKT){ierror(0);return;}
  234.         free(p);
  235.         p=merk;
  236.     }
  237. }
  238. int mcmp(const char *s1,const char *s2)
  239. /*  Einfachere strcmp-Variante.     */
  240. {
  241.     char c;
  242.     do{
  243.         c=*s1++;
  244.         if(c!=*s2++) return(1);
  245.     }while(c);
  246.     return(0);
  247. }
  248. void cpbez(char *m,int check_keyword)
  249. /*  Kopiert den naechsten Bezeichner von s nach m. Wenn check_keyord!=0 */
  250. /*  wird eine Fehlermeldung ausgegeben, falls das Ergebnis ein          */
  251. /*  reserviertes Keyword von C ist.                                     */
  252. {
  253.     char *p=m,*last=m+MAXI-1;int warned=0;
  254.     if(DEBUG&128) printf("Before cpbez:%s\n",s);
  255.     while(isalpha((unsigned char)*s)||isdigit((unsigned char)*s)||*s=='_'){
  256.         if(m<last){
  257.             *m++=*s++;
  258.         }else{
  259.             s++;
  260.             if(!warned){
  261.                 error(206,MAXI-1);
  262.                 warned=1;
  263.             }
  264.         }
  265.     }
  266.     *m=0;
  267.     if(DEBUG&128) printf("After cpbez:%s\n",s);
  268.     if(check_keyword){
  269.         char *n=p+1;
  270.         switch(*p){
  271.         case 'a': if(!mcmp(n,"uto")) error(216,p);
  272.                   return;
  273.         case 'b': if(!mcmp(n,"reak")) error(216,p);
  274.                   return;
  275.         case 'c': if(!mcmp(n,"ase")) error(216,p);
  276.                   if(!mcmp(n,"har")) error(216,p);
  277.                   if(!mcmp(n,"onst")) error(216,p);
  278.                   if(!mcmp(n,"ontinue")) error(216,p);
  279.                   return;
  280.         case 'd': if(!mcmp(n,"efault")) error(216,p);
  281.                   if(!mcmp(n,"o")) error(216,m);
  282.                   if(!mcmp(n,"ouble")) error(216,p);
  283.                   return;
  284.         case 'e': if(!mcmp(n,"lse")) error(216,p);
  285.                   if(!mcmp(n,"num")) error(216,p);
  286.                   if(!mcmp(n,"xtern")) error(216,p);
  287.                   return;
  288.         case 'f': if(!mcmp(n,"loat")) error(216,p);
  289.                   if(!mcmp(n,"or")) error(216,p);
  290.                   return;
  291.         case 'g': if(!mcmp(n,"oto")) error(216,p);
  292.                   return;
  293.         case 'i': if(!mcmp(n,"f")) error(216,p);
  294.                   if(!mcmp(n,"nt")) error(216,p);
  295.                   return;
  296.         case 'l': if(!mcmp(n,"ong")) error(216,p);
  297.                   return;
  298.         case 'r': if(!mcmp(n,"egister")) error(216,p);
  299.                   if(!mcmp(n,"eturn")) error(216,p);
  300.                   return;
  301.         case 's': if(!mcmp(n,"hort")) error(216,p);
  302.                   if(!mcmp(n,"igned")) error(216,p);
  303.                   if(!mcmp(n,"izeof")) error(216,p);
  304.                   if(!mcmp(n,"tatic")) error(216,p);
  305.                   if(!mcmp(n,"truct")) error(216,p);
  306.                   if(!mcmp(n,"witch")) error(216,p);
  307.                   return;
  308.         case 't': if(!mcmp(n,"ypedef")) error(216,p);
  309.                   return;
  310.         case 'u': if(!mcmp(n,"nion")) error(216,p);
  311.                   if(!mcmp(n,"nsigned")) error(216,p);
  312.                   return;
  313.         case 'v': if(!mcmp(n,"oid")) error(216,p);
  314.                   if(!mcmp(n,"olatile")) error(216,p);
  315.                   return;
  316.         case 'w': if(!mcmp(n,"hile")) error(216,p);
  317.                   return;
  318.         default : return;
  319.         }
  320.     }
  321. }
  322. void cpnum(char *m)
  323. /* kopiert die naechste int-Zahl von s nach m   */
  324. /* muss noch erheblich erweiter werden          */
  325. {
  326.     if(DEBUG&128) printf("Before cpnum:%s\n",s);
  327.     while(isdigit((unsigned char)*s)) *m++=*s++;
  328.     *m++=0;
  329.     if(DEBUG&128) printf("After cpnum:%s\n",s);
  330.  
  331. }
  332. static void killsp2(void)
  333. {
  334.     while(isspace((unsigned char)*s)) s++;
  335. }
  336. void killsp(void)
  337. /*  Ueberspringt Fuellzeichen                   */
  338. /*  noch einige unschoene Dinge drin            */
  339. {
  340.     int r;
  341.     if(DEBUG&128) printf("Before killsp:%s\n",s);
  342.     if(eof) raus();
  343.     while(isspace((unsigned char)*s)){
  344. /*        if(*s=='\n') {line++;if(DEBUG&1) printf("Line %d\n",line);}*/
  345.         s++;
  346.     }
  347.     if(*s==0){
  348.         do{
  349.             if(c_flags[17]&USEDFLAG) r=(fgets(string,MAXINPUT,in[0])!=0);
  350.                 else                 r=pp_nextline();
  351.             if(!r){
  352.                 /*raus();*/
  353.                 if(DEBUG&1) printf("nextline/fgets returned 0\n");
  354.                 s=string;*s=0;
  355.                 eof=1;
  356.                 return;
  357.             }else{
  358.                 line++;
  359.                 read_new_line=1;
  360.                 if(DEBUG&1) printf("Line %d\n",line);
  361.                 if(!strncmp("#pragma",string,7)){
  362.                     error(163);
  363.                     s=string+7;
  364.                     killsp2();
  365.                     if(!strncmp("opt",s,3)){
  366.                         s+=3;killsp2();
  367.                         c_flags_val[0].l=atol(s);
  368.                         if(DEBUG&1) printf("#pragma opt %ld\n",c_flags_val[0].l);
  369.                     }
  370.                     else if(!strncmp("printflike",s,10)){
  371.                         struct Var *v;
  372.                         s+=10;killsp2();
  373.                         cpbez(buff,0);
  374.                         if(DEBUG&1) printf("printflike %s\n",buff);
  375.                         v=find_var(buff,0);
  376.                         if(v){
  377.                             v->flags|=PRINTFLIKE;
  378.                             if(DEBUG&1) printf("succeeded\n");
  379.                         }
  380.                     }
  381.                     else if(!strncmp("scanflike",s,9)){
  382.                         struct Var *v;
  383.                         s+=9;killsp2();
  384.                         cpbez(buff,0);
  385.                         if(DEBUG&1) printf("scanflike %s\n",buff);
  386.                         v=find_var(buff,0);
  387.                         if(v){
  388.                             v->flags|=SCANFLIKE;
  389.                             if(DEBUG&1) printf("succeeded\n");
  390.                         }
  391.                     }
  392.                     else if(!strncmp("only-inline",s,11)){
  393.                         s+=11;killsp2();
  394.                         if(!strncmp("on",s,2)){
  395.                             if(DEBUG&1) printf("only-inline on\n");
  396.                             only_inline=1;
  397.                         }else{
  398.                             if(DEBUG&1) printf("only-inline off\n");
  399.                             only_inline=2;
  400.                         }
  401.                     }
  402.                     else if(!strncmp("type",s,4)){
  403.                     /*  Typ eines Ausdrucks im Klartext ausgeben    */
  404.                         np tree;
  405.                         s+=4;strcat(s,";");
  406.                         tree=expression();
  407.                         if(tree&&type_expression(tree)){
  408.                             printf("type of %s is:\n",string+7);
  409.                             prd(stdout,tree->ntyp);printf("\n");
  410.                         }
  411.                         if(tree) free_expression(tree);
  412.                     }
  413.                     else if(!strncmp("tree",s,4)){
  414.                     /*  gibt eine expression aus    */
  415.                         np tree;
  416.                         s+=4;strcat(s,";");
  417.                         tree=expression();
  418.                         if(tree&&type_expression(tree)){
  419.                             printf("tree of %s is:\n",string+7);
  420.                             pre(stdout,tree);printf("\n");
  421.                         }
  422.                         if(tree) free_expression(tree);
  423.                     }
  424.                 }
  425.                 if(string[0]=='#'&&isspace((unsigned char)string[1])&&isdigit((unsigned char)string[2])){
  426.                     sscanf(string+2,"%d \" %[^\"]",&line,errfname);
  427.                     if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
  428.                     line--;
  429.                 }
  430.                 if(!strncmp("#line ",string,6)){
  431.                     sscanf(string+6,"%d \" %[^\"]",&line,errfname);
  432.                     if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
  433.                     line--;
  434.                 }
  435.                 s=string;
  436.             }
  437.         }while(*s=='#');
  438.         killsp();
  439.     }
  440.     if(DEBUG&128) printf("After killsp:%s\n",s);
  441. }
  442. zlong szof(struct Typ *t)
  443. /*  liefert die benoetigte Groesse eines Typs in Bytes      */
  444. /*  maschinenabhaengig                                      */
  445. {
  446.     int i=t->flags,j,f;zlong size,m;
  447. /*    if(type_uncomplete(t)){
  448.         error(176);
  449.         return(0);
  450.     }*/
  451.     if((i&15)==POINTER) return(sizetab[POINTER]);
  452.     if((i&15)==ARRAY) return(zlmult((t->size),szof(t->next)));
  453.     if((i&15)==UNION){
  454.         for(j=0,size=l2zl(0L);j<t->exact->count;j++){
  455.             m=szof((*t->exact->sl)[j].styp);
  456.             if(zleqto(m,l2zl(0L))) return(l2zl(0L));
  457.             if(!zlleq(m,size)) size=m;
  458.         }
  459.         return(zlmult(zldiv(zladd(size,zlsub(align[UNION],l2zl(1L))),align[UNION]),align[UNION])); /* align */
  460.     }
  461.     if((i&15)==STRUCT){
  462.         for(j=0,size=0;j<t->exact->count;j++){
  463.             struct Typ *h=(*t->exact->sl)[j].styp;
  464.             m=szof(h);
  465.             if(zleqto(m,l2zl(0L))) return(l2zl(0L));
  466.             do{
  467.                 f=h->flags&15;
  468.                 h=h->next;
  469.             }while(f==ARRAY);
  470.             size=zlmult(zldiv(zladd(size,zlsub(align[f],l2zl(1L))),align[f]),align[f]);
  471.             size=zladd(size,m);
  472.         }
  473.         return(zlmult(zldiv(zladd(size,zlsub(align[STRUCT],l2zl(1L))),align[STRUCT]),align[STRUCT])); /* align */
  474.     }
  475.     if(DEBUG&2) printf("sizeof(%d)=%ld\n",i&15,zl2l(sizetab[i&15]));
  476.     return(sizetab[i&15]);
  477. }
  478. void enter_block(void)
  479. /*  Setzt Zeiger/Struckturen bei Eintritt in neuen Block    */
  480. {
  481.     if(nesting>=MAXN){error(9,nesting);return;}
  482.     nesting++;
  483.     if(DEBUG&1) printf("enter block %d\n",nesting);
  484.     first_ilist[nesting]=last_ilist[nesting]=0;
  485.     first_sd[nesting]=last_sd[nesting]=0;
  486.     first_si[nesting]=last_si[nesting]=0;
  487.     first_var[nesting]=last_var[nesting]=0;
  488.     if(nesting==1){
  489.         first_llist=last_llist=0;
  490.         first_clist=last_clist=0;
  491.         merk_varf=merk_varl=0;
  492.         merk_ilistf=merk_ilistl=0;
  493.         merk_sif=merk_sil=0;
  494. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  495. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  496. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  497. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  498. /*        merk_sdf=merk_sdl=0;*/
  499.         afterlabel=0;
  500.     }
  501. }
  502. void leave_block(void)
  503. /*  Setzt Zeiger/Struckturen bei Verlassen eines Blocks     */
  504. {
  505.     int i;
  506.     for(i=1;i<=MAXR;i++)
  507.         if(regbnesting[i]==nesting) regsbuf[i]=0;
  508.  
  509.     if(nesting<0){error(10);return;}
  510.     if(DEBUG&1) printf("leave block %d\n",nesting);
  511.     if(nesting>0){
  512.         if(merk_varl) merk_varl->next=first_var[nesting]; else merk_varf=first_var[nesting];
  513.         if(last_var[nesting]) merk_varl=last_var[nesting];
  514.         if(merk_sil) merk_sil->next=first_si[nesting]; else merk_sif=first_si[nesting];
  515.         if(last_si[nesting]) merk_sil=last_si[nesting];
  516.         if(merk_sdl) merk_sdl->next=first_sd[nesting]; else merk_sdf=first_sd[nesting];
  517.         if(last_sd[nesting]) merk_sdl=last_sd[nesting];
  518.         if(merk_ilistl) merk_ilistl->next=first_ilist[nesting]; else merk_ilistf=first_ilist[nesting];
  519.         if(last_ilist[nesting]) merk_ilistl=last_ilist[nesting];
  520.     }
  521.     if(nesting==1){
  522.         if(merk_varf) gen_vars(merk_varf);
  523.         if(first_llist) free_llist(first_llist);
  524.         if(first_clist) free_clist(first_clist);
  525.         if(merk_varf) free_var(merk_varf);
  526.         if(merk_sif) free_si(merk_sif);
  527. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  528. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  529. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  530. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  531. /*        if(merk_sdf) free_sd(merk_sdf);*/
  532.         if(merk_ilistf) free_ilist(merk_ilistf);
  533.     }
  534.     if(nesting==0){
  535. /*  struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden,     */
  536. /*  dass struct-declarations in Prototypen frei werden und dann eine        */
  537. /*  spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird.      */
  538. /*  Nicht sehr schoen - wenn moeglich noch mal aendern.                     */
  539.         if(merk_sdf) free_sd(merk_sdf);
  540.         if(first_var[0]) gen_vars(first_var[0]);
  541.         if(first_var[0]) free_var(first_var[0]);
  542.         if(first_sd[0]) free_sd(first_sd[0]);
  543.         if(first_si[0]) free_si(first_si[0]);
  544.         if(first_ilist[0]) free_ilist(first_ilist[0]);
  545.     }
  546.     nesting--;
  547. }
  548. void pra(FILE *f,struct argument_list *p)
  549. /*  Gibt argument_list umgekehrt auf Bildschirm aus             */
  550. {
  551.     if(p->next){ pra(f,p->next);fprintf(f,",");}
  552.     if(p->arg) pre(f,p->arg);
  553. }
  554. void pre(FILE *f,np p)
  555. /*  Gibt expression auf Bildschirm aus                          */
  556. {
  557.     int c;
  558.     c=p->flags;
  559.     if(p->sidefx) fprintf(f,"/");
  560.     if(p->lvalue) fprintf(f,"|");
  561.     if(c==CALL){fprintf(f,"call-function(");pre(f,p->left);fprintf(f,")(");
  562.                 if(p->alist) pra(f,p->alist);
  563.                 fprintf(f,")");return;}
  564.     if(c==CAST){fprintf(f,"cast(");pre(f,p->left);
  565.                 fprintf(f,"->");prd(f,p->ntyp);
  566.                 fprintf(f,")");return;}
  567.     if(c==MEMBER){if(p->identifier) fprintf(f,".%s",p->identifier);return;}
  568.     if(c==IDENTIFIER){if(p->identifier) fprintf(f,"%s",p->identifier);
  569.         fprintf(f,"+");printval(f,&p->val,LONG,1); return;}
  570.     fprintf(f,"%s(",ename[c]);
  571.     if(p->left) pre(f,p->left);
  572.     if(p->right){
  573.         fprintf(f,",");
  574.         pre(f,p->right);
  575.     }
  576.     fprintf(f,")");
  577.     if(c==CEXPR||c==PCEXPR){fprintf(f,"(value="); printval(f,&p->val,p->ntyp->flags,1); fprintf(f,")");}
  578. }
  579. void printval(FILE *f,union atyps *p,int t,int verbose)
  580. /*  Gibt atyps aus                                      */
  581. {
  582.     if(t==CHAR){if(verbose)fprintf(f,"C");vlong=zc2zl(p->vchar);printzl(f,vlong);}
  583.     if(t==(UNSIGNED|CHAR)){if(verbose)fprintf(f,"UC");vulong=zuc2zul(p->vuchar);printzul(f,vulong);}
  584.     if(t==SHORT){if(verbose)fprintf(f,"S");vlong=zs2zl(p->vshort);printzl(f,vlong);}
  585.     if(t==(UNSIGNED|SHORT)){if(verbose) fprintf(f,"US");vulong=zus2zul(p->vushort);printzul(f,vulong);}
  586.     if(t==FLOAT){if(verbose)fprintf(f,"F");vdouble=zf2zd(p->vfloat);printzd(f,vdouble);}
  587.     if(t==DOUBLE){if(verbose)fprintf(f,"D");printzd(f,p->vdouble);}
  588.     if(t==INT){if(verbose)fprintf(f,"I");vlong=zi2zl(p->vint);printzl(f,vlong);}
  589.     if(t==LONG){if(verbose)fprintf(f,"L");printzl(f,p->vlong);}
  590.     if(t==(UNSIGNED|INT)){if(verbose)fprintf(f,"UI");vulong=zui2zul(p->vuint);printzul(f,vulong);}
  591.     if(t==(UNSIGNED|LONG)){if(verbose)fprintf(f,"UL");printzul(f,p->vulong);}
  592.     /*  das hier ist nicht wirklich portabel    */
  593.     if(t==POINTER){if(verbose)fprintf(f,"P");vulong=zp2zul(p->vpointer);printzul(f,vulong);}
  594. }
  595. void pric2(FILE *f,struct IC *p)
  596. /*  Gibt ein IC aus */
  597. {
  598.     if(p->next&&p->next->prev!=p) ierror(0);
  599.     if(p->code>=LABEL&&p->code<=BRA){
  600.         if(p->code==LABEL)
  601.             fprintf(f,"L%d",p->typf);
  602.         else{
  603.             fprintf(f,"\t%s L%d",ename[p->code],p->typf);
  604.             if(p->q1.flags){ fprintf(f,",");probj(f,&p->q1,0);}
  605.         }
  606.     }else{
  607.         fprintf(f,"\t%s ",ename[p->code]);
  608.         if(p->typf&UNSIGNED) fprintf(f,"unsigned ");
  609.         if(p->typf) fprintf(f,"%s ",typname[p->typf&15]);
  610.         probj(f,&p->q1,p->typf);
  611.         if(p->q2.flags){fprintf(f,",");probj(f,&p->q2,p->typf);}
  612.         if(p->z.flags){fprintf(f,"->");probj(f,&p->z,p->typf);}
  613.         if(p->code==ASSIGN||p->code==PUSH||p->code==POP) fprintf(f," size=%ld",zl2l(p->q2.val.vlong));
  614.         if((p->code==SAVEREGS||p->code==RESTOREREGS)&&p->q1.reg) fprintf(f," except %s",regnames[p->q1.reg]);
  615.     }
  616.     fprintf(f,"\n");
  617. }
  618. void pric(FILE *f,struct IC *p)
  619. /*  Gibt IC-Liste auf dem Bildschirm aus                */
  620. {
  621.     while(p){
  622.         pric2(f,p);
  623. /*        if(p->q1.am||p->q2.am||p->z.am) ierror(0);*/
  624.         p=p->next;
  625.     }
  626. }
  627.  
  628. void error(int errn,...)
  629. /*  Behandelt Ausgaben wie Fehler und Meldungen */
  630. {
  631.     int type=err_out[errn].flags;
  632.     va_list vl;char *errstr="",*txt;
  633.     if(type&DONTWARN) return;
  634.     va_start(vl,errn);
  635.     if(type&WARNING) errstr="warning";
  636.     if(type&ERROR) errstr="error";
  637.     if(type&NOLINE){
  638.         printf("%s %d: ",errstr,errn);
  639.     }else if(type&INFUNC){
  640.         if((type&INIC)&&err_ic&&err_ic->line){
  641.             if(!(c_flags[17]&USEDFLAG)) txt=filename[incnesting];
  642.                 else txt=errfname;
  643.             printf("%s %d in line %d of \"%s\": ",errstr,errn,err_ic->line,txt);
  644.         }else{
  645.             printf("%s %d in function \"%s\": ",errstr,errn,cur_func);
  646.         }
  647.     }else{
  648.         int n;
  649.         {if(eof) printf(">EOF\n"); else printf(">%s",string);}
  650.         if(!(c_flags[17]&USEDFLAG)){
  651.             printf("\n");
  652.             n=linenr;txt=filename[incnesting];
  653.         }else{
  654.             n=line;txt=errfname;
  655.         }
  656.         if(c_flags[20]&USEDFLAG){   /*  strip-path from filename */
  657.             char *p=txt,c;
  658.             while(c=*p++)
  659.                 if(c==':'||c=='/'||c=='\\') txt=p;
  660.         }
  661.         printf("%s %d in line %d of \"%s\": ",errstr,errn,n,txt);
  662.     }
  663.     vprintf(err_out[errn].text,vl);
  664.     printf("\n");
  665.     va_end(vl);
  666.     if(type&ERROR){
  667.         errors++;
  668.         if(c_flags_val[8].l&&c_flags_val[8].l<=errors)
  669.             {printf("Maximum number of errors reached!\n");raus();}
  670.     }
  671.     if(type&FATAL){printf("aborting...\n");raus();}
  672. }
  673. void printzl(FILE *f,zlong x)
  674. /*  Konvertiert zlong nach ASCII                        */
  675. /*  basiert noch einigermassen auf                      */
  676. /*  Zweierkomplementdarstellung (d.h. -MIN>MAX)         */
  677. /*  Ausserdem muss max(abs(long))<=max(unsigned long)   */
  678. {
  679.     zlong zl;zulong zul;
  680.     zl=l2zl(0L);
  681.     if(zlleq(x,zl)&&!zleqto(x,l2zl(0L))){
  682.         fprintf(f,"-");zl=zul2zl(t_max[LONG]);
  683.         if(zlleq(x,zlsub(l2zl(0L),zl))&&!zleqto(x,zlsub(l2zl(0L),zl))){
  684.         /*  aufpassen, da -x evtl. >LONG_MAX    */
  685.             zul=t_max[LONG];
  686.             x=zladd(x,zl);
  687.         } else zul=ul2zul(0UL);
  688.         x=zlsub(l2zl(0L),x);
  689.         vulong=zl2zul(x);
  690.         zul=zuladd(zul,vulong);
  691.     }else zul=zl2zul(x);
  692.     printzul(f,zul);
  693. }
  694. void printzul(FILE *f,zulong x)
  695. /*  Konvertiert zulong nach ASCII                       */
  696. {
  697.     zulong zul;unsigned long l;
  698.     if(DEBUG&64) printf("printzul:%lu\n",x);
  699.     zul=ul2zul(10UL);
  700.     if(!zuleqto(zuldiv(x,zul),ul2zul(0UL))) printzul(f,zuldiv(x,zul));
  701.     zul=zulmod(x,zul);l=zul2ul(zul);
  702.     fprintf(f,"%c",(int)(l+'0'));
  703. }
  704. void printzd(FILE *f,zdouble x)
  705. /*  Konvertiert zdouble nach ASCII, noch nicht fertig   */
  706. {
  707.     fprintf(f,"fp-constant");
  708. }
  709. FILE *open_out(char *name,char *ext)
  710. /*  Haengt ext an name an und versucht diese File als output zu oeffnen */
  711. {
  712.     char *s,*p;FILE *f;
  713.     if(ext){
  714.         s=mymalloc(strlen(name)+strlen(ext)+2);
  715.         strcpy(s,name);
  716.         p=s+strlen(s);
  717.         while(p>=s){
  718.             if(*p=='.'){*p=0;break;}
  719.             p--;
  720.         }
  721.         strcat(s,".");
  722.         strcat(s,ext);
  723.     }else s=name;
  724.     f=fopen(s,"w");
  725.     if(!f) printf("Couldn't open <%s> for output!\n",s);
  726.     if(ext) free(s);
  727.     return(f);
  728. }
  729. void *mymalloc(size_t size)
  730. /*  Belegt Speicher mit Abfrage     */
  731. {
  732.     void *p;static int safe;
  733.     /*  Um ein Fehlschlagen bei size==0 zu vermeiden; nicht sehr schoen,    */
  734.     /*  aber das einfachste...                                              */
  735.     if(size==0) size=1;
  736.     if(!(p=malloc(size))){
  737.         error(12);
  738.         raus();
  739.     }
  740.     return(p);
  741. }
  742. void probj(FILE *f,struct obj *p,int t)
  743. /*  Gibt Objekt auf Bildschirm aus                      */
  744. {
  745.     if(p->am) ierror(0);
  746.     if(p->flags&DREFOBJ) fprintf(f,"(");
  747.     if(p->flags&VARADR) fprintf(f,"#");
  748.     if(p->flags&VAR) {
  749.         printval(f,&p->val,LONG,1);
  750.         if(p->v->storage_class==AUTO||p->v->storage_class==REGISTER){
  751.             if(p->flags®)
  752.                 fprintf(f,"+%s",regnames[p->reg]);
  753.             else
  754.                 fprintf(f,"+%ld(FP)", zl2l(p->v->offset));
  755.         }else{
  756.             if(p->v->storage_class==STATIC){
  757.                 fprintf(f,"+L%ld",zl2l(p->v->offset));
  758.             }else{
  759.                 fprintf(f,"+_%s",p->v->identifier);
  760.             }
  761.         }
  762.         fprintf(f,"(%s)",p->v->identifier);
  763.         if(p->v->reg) fprintf(f,":%s",regnames[p->v->reg]);
  764.     }
  765.     if((p->flags®)&&!(p->flags&VAR)) fprintf(f,"%s",regnames[p->reg]);
  766.     if(p->flags&KONST){
  767.         fprintf(f,"#");printval(f,&p->val,t&31,1);
  768.     }
  769.     if(p->flags&DREFOBJ) fprintf(f,")");
  770. }
  771.  
  772.